// http/index.ts
import baseApi from '@/conf'
import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { notification } from 'ant-design-vue'

// 封装axios 请求 新增 hideLoading 如需禁用 hideLoading传true
class request {
  service: AxiosInstance
  public constructor() {
    this.service = axios.create({
      baseURL: '',
      timeout: 6000, // 设置超时
      headers: {
        'Content-Type': 'application/json;charset=UTF-8;'
      }
    })

    // 请求拦截器
    this.service.interceptors.request.use(
      (config: any) => {
        if (config.url.startsWith('http') || !baseApi || baseApi.length === 0) {
          config.url = config.url
        } else {
          for (const api of baseApi) {
            if (config.url.startsWith(api.prefix)) {
              config.url = config.url.replace(api.prefix, api.url)
            }
          }
        }
        // 每次发送请求之前判断是否存在token，如果存在，则统一在http请求的header都加上token，不用每次请求都手动添加了
        const token = sessionStorage.getItem('ysys_token')
        token && (config.headers.Authorization = token)
        if (config.data && !config.data.appKey && config.data.appKey !== '') {
          config.data.appKey =
            sessionStorage.getItem('appKey') || '7a2a6182c10840e18c31c4e01512771e'
        }
        if (config.params && !config.params.appKey && config.params.appKey !== '') {
          config.params.appKey =
            sessionStorage.getItem('appKey') || '7a2a6182c10840e18c31c4e01512771e'
        }

        return config
      },
      (error) => {
        // 对请求错误做些什么
        return Promise.reject(error)
      }
    )

    // response interceptor
    this.service.interceptors.response.use(
      (response: AxiosResponse) => {
        if (response.data instanceof Blob) {
          return Promise.resolve(response)
        }
        if (typeof response.data === 'string') {
          return Promise.resolve(response)
        }
        if (
          response.data.code == '0' ||
          response.data.code == '200' ||
          response.data.responseCode == '100000000'
        ) {
          // 服务端定义的响应code码为0时请求成功
          // 使用Promise.resolve 正常响应
          return Promise.resolve(response.data)
        }
        notification.error({
          message: `错误码：${response.data.code || response.data.responseCode}`,
          description: response.data.message || response.data.responseMsg || 'Error'
        })
        return Promise.resolve(response.data)
      },
      (error: any) => {
        let message = ''
        if (error && error.response) {
          switch (error.response.status) {
            case 401:
              message = error.response.data.message
                ? `${error.response.data.path},${error.response.data.message}`
                : '无权访问'
              return
            case 403:
              message = error.response.data.message
                ? `${error.response.data.path},${error.response.data.message}`
                : '无权访问'
              break
            case 429:
              message = '访问太过频繁，请稍后再试!'
              break
            default:
              message = error.response.data.message ? error.response.data.message : '服务器错误'
              break
          }
          notification.error({
            message: `http状态码${error.response.status}`,
            description: message || 'Error'
          })
          // 请求错误处理
          return Promise.reject(error)
        }
        message = '连接服务器失败'
        notification.error({
          message: `http状态码${error.response.status}`,
          description: message || 'Error'
        })
        return Promise.reject(error)
      }
    )
  }
  get<T, D>(url: string, params?: D, config?: any): Promise<ResponseKVData<T>> {
    return this.service.get(url, {
      params: {
        ...params
      },
      ...config
    })
  }
  post<T, D>(url: string, data?: D, config?: any): Promise<ResponseKVData<T>> {
    return this.service.post(
      url,
      {
        ...data
      },
      { ...config }
    )
  }
  put<T, D>(url: string, data?: D, config?: any): Promise<ResponseKVData<T>> {
    return this.service.put(
      url,
      {
        ...data
      },
      { ...config }
    )
  }
  delete<T, D>(url: string, params?: D, config?: any): Promise<ResponseKVData<T>> {
    return this.service.delete(url, {
      params: {
        ...params
      },
      ...config
    })
  }
}

export default new request()
